"""
上传文件数据模型和操作 (models/upload.py)

处理上传文件记录的加载、保存和查询。
支持按日期存储和查询上传记录。
使用 MySQL 数据库作为数据存储。
"""
import os
from datetime import datetime
from config.config import APP_CONFIG
from models.db_models import Upload as UploadDB, Tag
from models import db_session
import logging

logger = logging.getLogger(__name__)

def get_date_folder_path(date=None):
    """
    获取指定日期的上传文件夹路径 (YYYYMMDD)。
    如果目录不存在则创建。

    Args:
        date: 日期对象 (可选, 默认当前 UTC 日期)

    Returns:
        tuple: (文件夹绝对路径, 日期字符串 YYYYMMDD)
    """
    if date is None:
        date = datetime.utcnow()
    date_str = date.strftime("%Y%m%d")
    folder_path = os.path.join(APP_CONFIG['UPLOAD_FOLDER'], date_str)
    os.makedirs(folder_path, exist_ok=True)
    return folder_path, date_str

def load_uploads(date_folder=None):
    """
    加载上传记录。
    从指定日期文件夹加载。

    Args:
        date_folder: 日期文件夹绝对路径 (可选)

    Returns:
        list: 上传记录列表。
    """
    try:
        session = db_session()
        
        # 如果指定了日期文件夹，则按日期过滤
        if date_folder:
            date_str = os.path.basename(date_folder)
            uploads_db = session.query(UploadDB).filter(UploadDB.date_folder == date_str).all()
        else:
            uploads_db = session.query(UploadDB).all()
            
        uploads = [upload.to_dict() for upload in uploads_db]
        session.close()
        return uploads
    except Exception as e:
        logger.error(f"从数据库加载上传数据时出错: {e}")
        return []

def get_upload_by_id(file_id, date_folder=None):
    """
    根据文件 ID 获取单个上传记录。
    
    Args:
        file_id: 文件ID
        date_folder: 日期文件夹路径 (可选)
        
    Returns:
        dict: 上传记录字典或None
    """
    try:
        session = db_session()
        upload = session.query(UploadDB).filter(UploadDB.id == file_id).first()
        result = upload.to_dict() if upload else None
        session.close()
        return result
    except Exception as e:
        logger.error(f"根据ID从数据库查询上传文件时出错: {e}")
        return None

def create_upload_record(file_id, original_name, saved_name, url, file_path, file_size=None, file_type=None, date_folder=None, analyzed=False, ai_analysis=None):
    """
    创建新的上传记录。
    保存到 MySQL 数据库。
    
    Args:
        file_id: 文件ID (UUID字符串)
        original_name: 原始文件名
        saved_name: 保存的文件名
        url: 访问URL
        file_path: 文件系统路径
        file_size: 文件大小 (字节)
        file_type: 文件MIME类型
        date_folder: 日期文件夹路径
        analyzed: 是否已经进行分析
        ai_analysis: AI分析结果
        
    Returns:
        dict: 上传记录字典
    """
    date_str = None
    if date_folder:
        date_str = os.path.basename(date_folder)
    
    created_at = datetime.utcnow()
    
    try:
        session = db_session()
        
        # 创建数据库记录
        upload_db = UploadDB(
            id=file_id,
            original_name=original_name,
            saved_name=saved_name,
            url=url,
            file_path=file_path,
            file_size=file_size,
            file_type=file_type,
            date_folder=date_str,
            created_at=created_at,
            analyzed=analyzed,
            tags=[],
            ai_analysis=ai_analysis
        )
        
        session.add(upload_db)
        session.commit()
        
        # 获取并返回数据
        upload_dict = upload_db.to_dict()
        session.close()
        return upload_dict
    except Exception as e:
        logger.error(f"创建上传记录到数据库时出错: {e}")
        if session:
            session.rollback()
            session.close()
        return None

def init_uploads_db():
    """
    初始化上传数据库。
    此方法为空，因为MySQL数据库通过models.db_models初始化。
    """
    pass

def get_upload_dates():
    """
    获取所有上传日期文件夹列表。
    
    Returns:
        list: 日期字符串列表 (YYYYMMDD格式)
    """
    try:
        session = db_session()
        
        # 查询所有不同的日期文件夹
        date_folders = session.query(UploadDB.date_folder).distinct().all()
        
        # 提取日期字符串并过滤掉None值
        dates = [date[0] for date in date_folders if date[0]]
        
        session.close()
        return dates
    except Exception as e:
        logger.error(f"获取上传日期列表时出错: {e}")
        return []

def update_upload_tags(file_id, tags):
    """
    更新上传记录的标签。
    
    Args:
        file_id: 文件ID
        tags: 标签列表
        
    Returns:
        dict: 更新后的上传记录，如果找不到记录则返回None
    """
    try:
        session = db_session()
        upload = session.query(UploadDB).filter(UploadDB.id == file_id).first()
        
        if not upload:
            logger.warning(f"更新标签失败：未找到上传记录 ID: {file_id}")
            session.close()
            return None
        
        # 获取现有标签以便更新计数
        old_tags = upload.tags.copy() if upload.tags else []
        
        # 更新上传记录的标签
        upload.tags = tags
        session.commit()
        
        # 更新标签计数
        update_tag_counts(old_tags, tags, session)
        
        # 转换为字典并返回
        result = upload.to_dict()
        session.close()
        return result
    except Exception as e:
        logger.error(f"更新上传记录标签时出错: {e}")
        if session:
            session.rollback()
            session.close()
        return None

def update_tag_counts(old_tags, new_tags, session):
    """
    更新标签出现次数统计。
    
    Args:
        old_tags: 旧标签列表
        new_tags: 新标签列表
        session: 数据库会话
    """
    try:
        from models.db_models import Tag
        
        # 处理移除的标签（减少计数）
        removed_tags = [tag for tag in old_tags if tag not in new_tags]
        for tag_name in removed_tags:
            tag = session.query(Tag).filter(Tag.name == tag_name).first()
            if tag and tag.count > 0:
                tag.count -= 1
        
        # 处理新增的标签（增加计数或创建新标签）
        added_tags = [tag for tag in new_tags if tag not in old_tags]
        for tag_name in added_tags:
            tag = session.query(Tag).filter(Tag.name == tag_name).first()
            if tag:
                tag.count += 1
                tag.last_used = datetime.utcnow()
            else:
                # 创建新标签
                new_tag = Tag(
                    name=tag_name,
                    count=1,
                    created_at=datetime.utcnow(),
                    last_used=datetime.utcnow()
                )
                session.add(new_tag)
        
        session.commit()
    except Exception as e:
        logger.error(f"更新标签统计时出错: {e}")
        session.rollback() 